#include <model.h>





void Model::readSkin_TXT( QString myFileString_Skin )
{


        QFile myFile(myFileString_Skin);

        myFile.open(QIODevice::ReadOnly);

        if( !myFile.isOpen() )
        {
            ErrorManager::error(3, myFileString_Skin);
            return;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        QTextStream myStream(&myFile);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        myStream >> totalSkinningBones;

        skinningSkeleton.skinningBones.clear();
        skinningSkeleton.skinningBones.resize(totalSkinningBones);

        Eigen::MatrixXd initialBonePoint(4,1);
                        initialBonePoint <<    0,0,0,1;

        for (int skkk=0; skkk<totalSkinningBones; skkk++)
        {
                skinningSkeleton.skinningBones[skkk].name           = "";
                skinningSkeleton.skinningBones[skkk].bone_Start_4x1 = initialBonePoint;
                skinningSkeleton.skinningBones[skkk].bone_Leaff_4x1 = initialBonePoint;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        for (int skkk=0; skkk<totalSkinningBones; skkk++)
        {
                myStream >> skinningSkeleton.skinningBones[skkk].name;

                if (skinningSkeleton.skinningBones[skkk].name == "Lower")
                {
                    QString     help1;
                    QString     help2;
                    myStream >> help1;
                    myStream >> help2;
                    skinningSkeleton.skinningBones[skkk].name = skinningSkeleton.skinningBones[skkk].name + " " + help1 + " " + help2;
                }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        if (skeleton.bones.size() > 0)
        {

                    for (int bbb=0; bbb<totalBones; bbb++)
                    {
                        for (int skk=0; skk<totalSkinningBones; skk++)
                        {

                                if (skinningSkeleton.skinningBones[skk].name == skeleton.bones[bbb].name)
                                {
                                    skeleton.bones[bbb].isUsedForSkinning = true;

                                    skeleton.bones[bbb].addressSeListaSKINNING = skk;
                                }

                        }
                    }

        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        skin.skinnedVertices.clear();
        skin.skinnedVertices.resize(totalVertices);

        for (int vvv=0; vvv<totalVertices; vvv++)
        {

                skin.skinnedVertices[vvv].skinWeights.resize(totalSkinningBones);

                double vertexSUM = 0;

                for (int skkk=0; skkk<totalSkinningBones; skkk++)
                {
                    myStream  >> skin.skinnedVertices[vvv].skinWeights[skkk];

                    vertexSUM += skin.skinnedVertices[vvv].skinWeights[skkk];
                }

                /////////////////////////////////////////////////
                // Normalize Weights to sum up to 1, combating //
                // rounding numerical issues in the txt file   //
                /////////////////////////////////////////////////
                for (int skkk=0; skkk<totalSkinningBones; skkk++)
                {
                    skin.skinnedVertices[vvv].skinWeights[skkk] /= vertexSUM;
                }

        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        myFile.close();

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}




void Model::test_SkinningWeihgts_sum_to_1()
{

        for (int vvv=0; vvv<totalVertices; vvv++)
        {

                double testSUM = 0;

                for (int skkk=0; skkk<totalSkinningBones; skkk++)
                {
                    testSUM += skin.skinnedVertices[vvv].skinWeights[skkk];
                }

                if (testSUM == 1)   std::cout << vvv << "\t" << testSUM                                << std::endl;
                else                std::cout << vvv << "\t" << testSUM << "\t#######################" << std::endl;

        }

}




/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




void Model::print_SkinningWeights()
{

        for (int vvv=0; vvv<totalVertices; vvv++)
        {

            std::cout << vvv << "\t";

            for (int skkk=0; skkk<totalSkinningBones; skkk++)
            {

                std::cout << skin.skinnedVertices[vvv].skinWeights[skkk] << " ";

            }

            std::cout << std::endl << std::endl;

        }

}


void Model::print_SkinningBones()
{

        for (int skkk=0; skkk<totalSkinningBones; skkk++)
        {
            std::cout << skkk << "\t" << skinningSkeleton.skinningBones[skkk].name.toStdString() << std::endl;
        }

        std::cout << std::endl << std::endl;

}


